// Display a dialog containing error messages
#include "burner.h"
#include <richedit.h>

static wchar_t* pszBufferEnglish = NULL;
static wchar_t* pszBufferLocal = NULL;

static int bufferEnglishSize = 0;
static int bufferLocalSize = 0;

static int popupFlags;

static HFONT hEditFont;
static int nIcon;

// ----------------------------------------------------------------------------
// Log the popup message to the debug log/console

static int FBAPopupLog()
{
	wchar_t* strEnglish;

	switch (popupFlags & 7) {
		case PUF_TYPE_ERROR:
			strEnglish = localiseStringEx(IDS_ERR_ERROR, false);
			break;
		case PUF_TYPE_WARNING:
			strEnglish = localiseStringEx(IDS_ERR_WARNING, false);
			break;
		default:
			strEnglish = localiseStringEx(IDS_ERR_INFORMATION, false);
			break;
	}

	dprintf("*** %s message:\n", WtoA(strEnglish));

	for (wchar_t* szText = pszBufferEnglish; ; ) {
		unsigned len;
		for (len = 0; szText[len] && szText[len] != '\n'; len++) { }

		if (len) {
			char szFormat[32];
			sprintf(szFormat, "    %%.%is\n", len);
			dprintf(szFormat, szText);
		}

		if (!szText[len]) {
			break;
		}

		szText += len + 1;
	}

	return 0;
}

// ----------------------------------------------------------------------------

static INT_PTR CALLBACK FBAPopupProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
		// Grab the handle to the font we need to use
		case WM_SETFONT: {
			hEditFont = (HFONT)wParam;
			break;
		}

		case WM_DRAWITEM: {
			if (((LPDRAWITEMSTRUCT)lParam)->CtlID == IDC_MESSAGE_ICON) {
				DrawIconEx(((LPDRAWITEMSTRUCT)lParam)->hDC, 0, 0, (HICON)LoadImage(NULL, MAKEINTRESOURCE(nIcon), IMAGE_ICON, 0, 0, LR_LOADTRANSPARENT | LR_SHARED), 32, 32, 0, NULL, DI_NORMAL | DI_DEFAULTSIZE);
			}

			break;
		}

		case WM_INITDIALOG: {
			int beep = -1;
			wchar_t caption[1024];
			wchar_t* strEnglish;
			wchar_t* strLocal;

			nIcon = 0;

			switch (popupFlags & 7) {
				case PUF_TYPE_ERROR:
					nIcon = OIC_ERROR;
					beep = MB_ICONHAND;
					strEnglish = localiseStringEx(IDS_ERR_ERROR, false);
					strLocal = localiseStringEx(IDS_ERR_ERROR);
					break;
				case PUF_TYPE_WARNING:
					nIcon = OIC_WARNING;
					beep = MB_ICONEXCLAMATION;
					strEnglish = localiseStringEx(IDS_ERR_WARNING, false);
					strLocal = localiseStringEx(IDS_ERR_WARNING);
					break;
				default:
					nIcon = OIC_INFORMATION;
					beep = MB_ICONASTERISK;
					strEnglish = localiseStringEx(IDS_ERR_INFORMATION, false);
					strLocal = localiseStringEx(IDS_ERR_INFORMATION);
					break;
			}

			// Set the icon
			SendDlgItemMessage(hDlg, IDC_MESSAGE_ICON, STM_SETIMAGE, IMAGE_ICON, (LPARAM)LoadImage(NULL, MAKEINTRESOURCE(nIcon), IMAGE_ICON, 32, 32, LR_SHARED));

			// Set the caption
			_snwprintf(caption, sizearray(caption), APP_TITLE L" %s", strLocal);
			SetWindowText(hDlg, caption);

			{
				SIZE sizee = { 0, 0 };
				SIZE sizel = { 0, 0 };
				POINT p = { 0, 0 };
				RECT rect;
				HWND hWnd;

				{
					hWnd = GetDlgItem(hDlg, IDC_MESSAGE_EDIT_ENG);
					HDC hDC = GetDC(hWnd);
					HFONT hFont = (HFONT)SelectObject(hDC, hEditFont);

					for (wchar_t* szText = pszBufferEnglish; ; ) {

						SIZE line;
						unsigned len;

						for (len = 0; szText[len] && szText[len] != '\n'; len++) { }

						GetTextExtentPoint32(hDC, szText, len ? len : 1, &line);

						if (sizee.cx < line.cx) {
							sizee.cx = line.cx;
						}
						sizee.cy += line.cy;

						if (!szText[len]) {
							break;
						}

						szText += len + 1;
					}

					if (bLanguageActive && pszBufferLocal) {
						for (wchar_t* szText = pszBufferLocal; ; ) {

							SIZE line;
							unsigned len;

							for (len = 0; szText[len] && szText[len] != '\n'; len++) { }

							GetTextExtentPoint32(hDC, szText, len ? len : 1, &line);

							if (sizel.cx < line.cx) {
								sizel.cx = line.cx;
							}
							sizel.cy += line.cy;

							if (!szText[len]) {
								break;
							}

							szText += len + 1;
						}
					}

					SelectObject(hDC, hFont);
					ReleaseDC(hWnd, hDC);
				}

				// Set minimum size if needed
				hWnd = GetDlgItem(hDlg, IDOK);
				GetWindowRect(hWnd, &rect);
				if (sizee.cx < (rect.right - rect.left)) {
					sizee.cx = rect.right - rect.left;
				}

				ClientToScreen(hDlg, &p);
				GetWindowRect(hDlg, &rect);

				// Size dialog and edit control containing message text
				if (bLanguageActive && pszBufferLocal) {

					if (sizel.cx < sizee.cx) {
						sizel.cx = sizee.cx;
					} else {
						sizee.cx = sizel.cx;
					}
					if (sizel.cy < 32) {
						sizel.cy = 32;
					}

					MoveWindow(hDlg, rect.left, rect.top, rect.right - rect.left + sizee.cx, rect.bottom - rect.top + sizee.cy + sizel.cy + 12, FALSE);

					hWnd = GetDlgItem(hDlg, IDC_MESSAGE_EDIT_LOCAL);
					GetWindowRect(hWnd, &rect);
					SetWindowPos(hWnd, NULL, 0, 0, rect.right - rect.left + sizel.cx, rect.bottom - rect.top + sizel.cy, SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW);
					SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)pszBufferLocal);
					SendMessage(hWnd, EM_SETMARGINS, EC_LEFTMARGIN, 3);
					ShowWindow(hWnd, SW_SHOW);

					hWnd = GetDlgItem(hDlg, IDC_MESSAGE_BACK);
					SetWindowPos(hWnd, NULL, 0, 0, 9999, rect.bottom - p.y + sizel.cy + 6, SWP_NOZORDER | SWP_NOREDRAW);
					ShowWindow(hWnd, SW_SHOW);

					p.y -= rect.bottom - rect.top + sizel.cy + 12;
				} else {
					if (sizee.cy < 32) {
						sizee.cy = 32;
					}

					MoveWindow(hDlg, rect.left, rect.top, rect.right - rect.left + sizee.cx, rect.bottom - rect.top + sizee.cy, FALSE);
				}

				hWnd = GetDlgItem(hDlg, IDC_MESSAGE_EDIT_ENG);
				SendMessage(hWnd, EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_3DFACE));
				GetWindowRect(hWnd, &rect);
				SetWindowPos(hWnd, NULL, rect.left - p.x, rect.top - p.y, rect.right - rect.left + sizee.cx, rect.bottom - rect.top + sizee.cy, (pszBufferLocal ? 0 : SWP_NOMOVE) | SWP_NOZORDER | SWP_NOREDRAW);
				SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)pszBufferEnglish);
				SendMessage(hWnd, EM_SETMARGINS, EC_LEFTMARGIN, 3);

				// Center button
				GetClientRect(hDlg, &rect);
				p.x = (rect.right - rect.left) / 2;
				hWnd = GetDlgItem(hDlg, IDOK);
				GetWindowRect(hWnd, &rect);
				SetWindowPos(hWnd, NULL, p.x - (rect.right - rect.left) / 2, rect.top - p.y + sizee.cy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
			}

			wndInMid(hDlg, hScrnWnd);
			SetForegroundWindow(hDlg);
			MessageBeep(beep);

			return TRUE;
		}
		case WM_COMMAND: {
			if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK
				|| HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDCANCEL) {
				SendMessage(hDlg, WM_CLOSE, 0, 0);
			}
			break;
		}
		case WM_CLOSE: {
			EndDialog(hDlg, 0);
			break;
		}
	}

	return 0;
}

// ----------------------------------------------------------------------------

int FBAPopupAddText(int nFlags, wchar_t* pszFormat, ...)
{
	wchar_t szString[1024];
	wchar_t* pszStringEnglish = NULL;

	va_list vaEnglish;
	va_start(vaEnglish, pszFormat);

	wchar_t szEngString[1024];
	if (IS_INTRESOURCE(pszFormat)) {
		wcsncpy(szEngString, localiseStringEx((UINT)pszFormat, false), sizearray(szEngString));
		pszStringEnglish = szEngString;
	} else {
		pszStringEnglish = pszFormat;
	}

	// See if we need to load strings from reources
	if (nFlags & PUF_TEXT_TRANSLATE) {
		wchar_t* pszStringLocal;

		va_list vaLocal;
		va_start(vaLocal, pszFormat);

		if (IS_INTRESOURCE(pszFormat)) {
			pszStringLocal = localiseStringEx((UINT)pszFormat);
		} else {
			pszStringLocal = pszFormat;
		}

		// Add the translated string if present
		if (bLanguageActive && (nFlags & PUF_TEXT_TRANSLATE) &&  pszStringLocal && *pszStringLocal) {
			// Add the translated string
			int len = _vsnwprintf(szString, sizearray(szString), pszStringLocal, vaLocal);
			if (len > 0) {
				wchar_t* pszNewBuffer = (wchar_t*)realloc(pszBufferLocal, (len + bufferLocalSize + 1) * sizeof(wchar_t));
				if (pszNewBuffer) {
					pszBufferLocal = pszNewBuffer;
					wcsncpy(pszBufferLocal + bufferLocalSize, szString, len);
					bufferLocalSize += len;
					pszBufferLocal[bufferLocalSize] = 0;
				}
			}
		}

		va_end(vaLocal);
	}

	// Add the English language string
	if (pszStringEnglish && *pszStringEnglish) {
		int len = _vsnwprintf(szString, sizearray(szString), pszStringEnglish, vaEnglish);
		if (len > 0) {
			wchar_t* pszNewBuffer = (wchar_t*)realloc(pszBufferEnglish, (len + bufferEnglishSize + 1) * sizeof(wchar_t));
			if (pszNewBuffer) {
				pszBufferEnglish = pszNewBuffer;
				wcsncpy(pszBufferEnglish + bufferEnglishSize, szString, len);
				bufferEnglishSize += len;
				pszBufferEnglish[bufferEnglishSize] = 0;
			}
		}
	}

	va_end(vaEnglish);

	return 0;
}

int FBAPopupDestroyText()
{
	free(pszBufferEnglish);
	pszBufferEnglish = NULL;
	bufferEnglishSize = 0;

	free(pszBufferLocal);
	pszBufferLocal = NULL;
	bufferLocalSize = 0;

	return 0;
}

// ----------------------------------------------------------------------------

int FBAPopupDisplay(int nFlags)
{
	popupFlags = nFlags;

	splashDestroy(true);

	FBAPopupLog();

	if (!(popupFlags & PUF_TYPE_LOGONLY)) {
		localiseDialogBox(IDD_POPUP, hSelDlg ? hSelDlg : hScrnWnd, (DLGPROC)FBAPopupProc);
	}

	FBAPopupDestroyText();

	return 1;
}
